/**
 *  Copyright ${date} Matthew Cline
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package factbook;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.w3c.tidy.Tidy;

/**
 * A DOM parser for the HTML pages of the CIA World Factbook.
 * This parser is pretty weak and highly dependent upon the HTML structure of the page.
 * 
 * @author Matthew Cline
 *
 */
public class FactbookWebParser {
	boolean debug = false;
	
	Tidy parser;
	ByteArrayOutputStream tidyErrors;
	OutputStream out;
	Document doc;
	
	public FactbookWebParser(BufferedInputStream in) {
		parser = new Tidy();
		tidyErrors = new ByteArrayOutputStream();
		parser.setErrout(new PrintWriter(tidyErrors));
		
		if(debug){
			out = System.err;
		} else {
			out = null;
		}
		
		doc = parser.parseDOM(in, null);
	}
	
	protected String get(String fips, String field) {
		String results = "";
		
		// parse page to find the specific field we want
		// Roll through each row on the page
		NodeList rows = doc.getElementsByTagName("tr");
		for(int i = 0; i < rows.getLength(); i++) {
			if(debug){System.err.println("Process row: " + i);}
			Element row = (Element)rows.item(i);
			NodeList cells;
			// Now role through each cell in the row
			if(row.hasChildNodes()) {
				cells = row.getElementsByTagName("td");
			} else {
				continue;
			}
			
			// First cell should have a class attribute of "FieldHeader", otherwise skip this row
			NamedNodeMap attributes = cells.item(0).getAttributes();
			if(attributes.getNamedItem("class") != null) {
				if(debug){System.err.println("Field header: " + attributes.getNamedItem("class").getNodeValue());}
				if(attributes.getNamedItem("class").getNodeValue().equals("FieldLabel")) {
				// Check to see if this Field Header matches the one we want
				Element cell = (Element)cells.item(0);
				NodeList headers = cell.getElementsByTagName("div");
					headers.item(0).getFirstChild().normalize();
					if(debug){System.err.println(headers.item(0).getFirstChild().getNodeValue());}
					if(headers.item(0).getFirstChild().getNodeValue().equals(field)) {
						// We found a match, so get the field value
						// Field value should be second cell of row
						NodeList values = cells.item(1).getChildNodes();
						for(int k = 0; k < values.getLength(); k++) {
							if(values.item(k).getNodeName().equals("#text")) {
								results = results + values.item(k).getNodeValue();
							}
						}
						results = results.trim();
						
						// Found a match, so get out of here
						break;
					} else {
						// No match, so check next row
						continue;
					}
				} else {
					continue;
				}
			} else {
				continue;
			}
		}
		return results;
	}
}
